package com.yuyou.hxyy.service.api.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import com.yuyou.hxyy.service.api.mapper.DataImportMapper;
import com.yuyou.hxyy.service.api.util.*;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
import com.yuyou.hxyy.service.api.bean.Pagination;
import com.yuyou.hxyy.service.api.cons.CommCons;
import com.yuyou.hxyy.service.api.entity.AuthUser;
import com.yuyou.hxyy.service.api.entity.DataImport;
import com.yuyou.hxyy.service.api.enums.CommEnums;
import com.yuyou.hxyy.service.api.enums.UserEnums;
import com.yuyou.hxyy.service.api.mapper.AuthUserMapper;
import com.yuyou.hxyy.service.api.service.IAuthUserService;
import com.yuyou.hxyy.service.api.vo.req.UserExcel;

@Service
public class AuthUserServiceImpl implements IAuthUserService {

	@Autowired
	private AuthUserMapper authUserMapper;

	@Autowired
	private DataImportMapper dataImportMapper;
	
	@Override
	public int deleteByPrimaryKey(Long id) {
		return authUserMapper.deleteByPrimaryKey(id);
	}

	@Override
	public int insert(AuthUser record) {
		record.setAuthUserId(Sequence.getSequence().nextId());
		record.setCreateTime(new Date());
		return authUserMapper.insert(record);
	}

	@Override
	public AuthUser selectByPrimaryKey(Long id) {
		return authUserMapper.selectByPrimaryKey(id);
	}

	@Override
	public int updateByPrimaryKeySelective(AuthUser record) {
		record.setUpdateTime(new Date());
		return authUserMapper.updateByPrimaryKeySelective(record);
	}

	@Override
	public AuthUser seleteAuthUserByAccount(String account) {
		return authUserMapper.seleteAuthUserByAccount(account);
	}
	@Override
	public AuthUser seleteByAccount7Type(String account,Integer userType) {
		return authUserMapper.seleteByAccount7Type(account,userType);
	}
		
	@Override
	public DataImport saveUserImport(List<UserExcel> userExcelList) {
		int total = userExcelList.size();

		// 校验导入数据
		List<UserExcel> failUserList = checkUserImport(userExcelList);

		List<AuthUser> authUserList = new ArrayList<>();
		for(UserExcel userExcel : userExcelList){
			AuthUser authUser = new AuthUser();
			DefindBeanUtils.copyProperties(userExcel, authUser);
			authUser.setAuthUserId(Sequence.getSequence().nextId());
			authUser.setPassword(MD5Util.md5Hex(MD5Util.md5Hex(CommCons.INIT_PASSWORD,CommCons.INIT_PASSWORD_FRONT_SALT),CommCons.INIT_PASSWORD_ADMIN_SALT));
			authUser.setSex("男".equals(userExcel.getSex()) ? UserEnums.sex.male.getValue():(
					"女".equals(userExcel.getSex()) ? UserEnums.sex.female.getValue():UserEnums.sex.unknown.getValue()));
			authUser.setStatus(UserEnums.status.normal.getValue());
			authUser.setUserType(UserEnums.userType.student.getValue());
			authUser.setSection(getSection(userExcel.getSection()));
			authUser.setUpdateTime(DateUtil.now());
			authUser.setCreateTime(DateUtil.now());
			authUserList.add(authUser);

		}

		if(authUserList.size() > 0){
			authUserMapper.batchInsertAuthUser(authUserList);
		}


		/** 导入成败记录 */
		DataImport dataImport = new DataImport();
		dataImport.setId(Sequence.getSequence().getNextId());
		dataImport.setTotal(total);
		dataImport.setSuccNum(userExcelList.size());
		dataImport.setFailNum(failUserList.size());
		dataImport.setStatus(failUserList.size() > 0 ? "1" : "0");
		dataImport.setType(CommEnums.resourceType.user.getValue());
		dataImport.setContent(JSON.toJSONString(failUserList));
		dataImport.setCreateTime(DateUtil.now());
		dataImportMapper.insert(dataImport);

		return dataImport;
	}

	@Override
	public int findAuthUserPageCount(Pagination<AuthUser> p) {
		return authUserMapper.findAuthUserPageCount(p);
	}

	@Override
	public List<AuthUser> findAuthUserPageList(Pagination<AuthUser> p) {
		return authUserMapper.findAuthUserPageList(p);
	}

	@Override
	@Transactional
	public void batchChangeAuthUserStatus(List<Long> ids, Integer status) {
		for(Long id : ids){
			AuthUser authUser = new AuthUser();
			authUser.setAuthUserId(id);
			authUser.setStatus(status);
			//如果是解冻，重置登录失败次数
			if(status==UserEnums.status.normal.getValue()){
				authUser.setLoginErr(0);
			}
			updateByPrimaryKeySelective(authUser);
		}
	}


	private List<UserExcel> checkUserImport(List<UserExcel> userExcelList){
		// 导入失败的用户
		List<UserExcel> failUserList = new ArrayList<>();
		Iterator<UserExcel> iterator = userExcelList.iterator();
		Set<String> accountSet = new HashSet<>();
		while(iterator.hasNext()){
			UserExcel userExcel = iterator.next();
			UserExcel failUser = new UserExcel();
			DefindBeanUtils.copyProperties(userExcel, failUser);
			StringBuilder failReason = new StringBuilder();


			if(StringUtils.isEmpty(userExcel.getUsername())){
				failReason.append(";").append("姓名为空");
			}else if(userExcel.getUsername().trim().length() > 50){
				failReason.append(";").append("姓名长度大于50");
			}

			if(StringUtils.isEmpty(userExcel.getAccount())){
				failReason.append(";").append("帐号为空");
			}else if(accountSet.contains(userExcel.getAccount().trim())){
				failReason.append(";").append("导入文件中该帐号已经存在");
			}else if(null != seleteAuthUserByAccount(userExcel.getAccount().trim())){
				// 帐号检测
				failReason.append(";").append("该帐号已经存在");
			}else{
				accountSet.add(userExcel.getAccount().trim());
			}
			if(StringUtils.isEmpty(userExcel.getSection())){
				failReason.append(";").append("年级为空");
			}else if(0 == getSection(userExcel.getSection())){
				failReason.append(";").append("年级有误");
			}

			// 性别
			List<String> genders = Arrays.asList("男","女","未知");
			if(!StringUtils.isEmpty(userExcel.getSex()) && !genders.contains(userExcel.getSex())){
				failReason.append(";").append("性别有误");
			}

			if(!StringUtils.isEmpty(userExcel.getPhone()) && !Validator.isMobile(userExcel.getPhone())){
				failReason.append(";").append("手机号有误");
			}

			// 不符合的，移除不导入
			if(!StringUtils.isEmpty(failReason.toString())){
				failUser.setFailedReason(failReason.toString().substring(1, failReason.toString().length()));
				failUserList.add(failUser);
				iterator.remove();
			}
		}

		return failUserList;
	}

	private Integer getSection(String section){
		switch (section){
			case "一年级":
				return 1;
			case "二年级":
				return 2;
			case "三年级":
				return 3;
			case "四年级":
				return 4;
			case "五年级":
				return 5;
			case "六年级":
				return 6;
			case "初一":
				return 7;
			case "初二":
				return 8;
			case "初三":
				return 9;
			case "高一":
				return 10;
			case "高二":
				return 11;
			case "高三":
				return 12;
			default:
				return 0;
		}
	}

	@Override
	public XSSFWorkbook failedInfoOfUserImport(List<UserExcel> userExcelList){

		XSSFWorkbook excel = new XSSFWorkbook();

		XSSFSheet sheet = excel.createSheet("导入失败信息");

		XSSFRow firstRow = sheet.createRow(0);

		String[] titles = new String[] { "帐号","姓名","手机号","性别","年级","导入失败原因"};

		for (int i = 0; i < titles.length; i++) {
			XSSFCell cell = firstRow.createCell(i);

			// 失败原因设置为红色
			if(i == titles.length -1){
				XSSFCellStyle cellStyle = excel.createCellStyle();
				cellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());
				cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
				cell.setCellStyle(cellStyle);
			}
			cell.setCellValue(titles[i]);
		}

		for (int i = 0; i < userExcelList.size(); i++ ) {

			UserExcel userExcel = userExcelList.get(i);

			XSSFRow row = sheet.createRow(i + 1);

			int c = 0;
			XSSFCell cell = row.createCell(c++);
			cell.setCellValue(userExcel.getAccount());

			cell = row.createCell(c++);
			cell.setCellValue(userExcel.getUsername());

			cell = row.createCell(c++);
			cell.setCellValue(userExcel.getPhone());

			cell = row.createCell(c++);
			cell.setCellValue(userExcel.getSex());

			cell = row.createCell(c++);
			cell.setCellValue(userExcel.getSection());

			cell = row.createCell(c++);
			// 失败原因设置为红色
			XSSFCellStyle cellStyle = excel.createCellStyle();
			cellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());
			cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
			cell.setCellStyle(cellStyle);
			cell.setCellValue(userExcel.getFailedReason());
		}
		return excel;
	}

}